#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace KLib.PostProcessing
{
    public class PostProcessingEffect
    {
        #region Fields
        protected PostProcessingManager manager;
        protected Effect effect;
        protected bool enabled;

        protected Dictionary<string, object> parameters = new Dictionary<string,object>();
        #endregion

        #region Properties
        public PostProcessingManager Manager
        {
            get { return manager; }
            internal set { manager = value; }
        }
        public Effect Effect
        {
            get { return effect;}
        }

        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }
        #endregion

        #region Initialization

        public PostProcessingEffect(){ }

        public PostProcessingEffect(Effect effect)
        {
            this.effect = effect;
        }

        public virtual void LoadContent()
        {
        }
        #endregion

        #region Methods
        public void Begin()
        {
            effect.Begin(SaveStateMode.None);
            effect.Techniques[0].Passes[0].Begin();
            SetParameters();
        }

        public void End()
        {
            effect.Techniques[0].Passes[0].End();
            effect.End();
        }

        public virtual void Update(GameTime gameTime)
        {
        }

        public void Toggle()
        {
            enabled = !enabled;
        }
        public void SetParameter(string parameterName, object value)
        {
            parameters[parameterName] = value;
        }
        #endregion

        #region Helper Methods
        protected virtual void SetParameters()
        {
            foreach (KeyValuePair<string, object> param in parameters)
            {
                Type type = param.Value.GetType();
                if (param.Value is float)
                    effect.Parameters[param.Key].SetValue((float)param.Value);
                else if (param.Value is bool)
                    effect.Parameters[param.Key].SetValue((bool)param.Value);
                else if (param.Value is Vector2)
                    effect.Parameters[param.Key].SetValue((Vector2)param.Value);
                else if (param.Value is Vector3)
                    effect.Parameters[param.Key].SetValue((Vector3)param.Value);
                else if (param.Value is Vector4)
                    effect.Parameters[param.Key].SetValue((Vector4)param.Value);
                else if (param.Value is Texture)
                    effect.Parameters[param.Key].SetValue((Texture)param.Value);
                else if (param.Value is float[])
                    effect.Parameters[param.Key].SetValue((float[])param.Value);
                else if (param.Value is bool[])
                    effect.Parameters[param.Key].SetValue((bool[])param.Value);
                else if (param.Value is Vector2[])
                    effect.Parameters[param.Key].SetValue((Vector2[])param.Value);
                else if (param.Value is Vector3[])
                    effect.Parameters[param.Key].SetValue((Vector3[])param.Value);
                else if (param.Value is Vector4[])
                    effect.Parameters[param.Key].SetValue((Vector4[])param.Value);
            }
        }
        #endregion
    }
}
